package com.ccorp.cface.collector;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.ccorp.cface.model.PageInfo;
import com.ccorp.cface.model.PageTrendInfo;
import com.ccorp.cface.model.PostInfo;
import com.ccorp.cface.model.PostTrendInfo;

import facebook4j.Facebook;
import facebook4j.FacebookException;
import facebook4j.FacebookFactory;
import facebook4j.Page;
import facebook4j.Post;
import facebook4j.Reading;
import facebook4j.ResponseList;
import facebook4j.internal.org.json.JSONArray;
import facebook4j.internal.org.json.JSONException;
import facebook4j.internal.org.json.JSONObject;

public class FacebookCollector implements ICollector {
	//Even though you can use https://graph.facebook.com/posts?ids=255057814552667,184572924024
	//{"query1":"SELECT type,post_id,created_time,actor_id,target_id,message,attachment.media,attachment.caption,attachment.name,attachment.description,attachment.fb_checkin,likes.count,likes.user_likes,likes.can_like,comment_info,description FROM stream WHERE source_id IN (255057814552667,184572924024) AND created_time<now() ORDER BY created_time DESC","query2":"SELECT id,name,pic FROM profile WHERE id IN (SELECT actor_id,target_id FROM #query1)"}
	private static String GET_POST_TREND_SUMMARY ="SELECT like_info.like_count, comment_info.comment_count, share_count FROM stream WHERE post_id = \"%s\"";
	private static String GET_PAGES_IN_COUNTRY = "SELECT page_id,name, page_url,fan_count FROM page WHERE CONTAINS('%s') AND location.country='%s' ORDER BY fan_count desc LIMIT %d OFFSET %d";
	private static String GET_PAGES_NO_COUNTRY = "SELECT page_id,name, page_url,fan_count FROM page WHERE CONTAINS('%s') AND strpos(lower(name), '%s') >=0 AND location.country='' ORDER BY fan_count DESC LIMIT %d OFFSET %d";
	private static int PAGE_SIZE = 500;
	private static SimpleDateFormat formatter;
	private static Facebook facebook; 
	static {
		facebook = new FacebookFactory().getInstance();
		formatter = new SimpleDateFormat("yyyy-MM-dd");
	}
	public static void main(String arg[])
	{	  
		//java.io.FileInputStream
		try {
			searchPages1();
		} catch (FacebookException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	private static int importWordsFromFile(ArrayList<String> arl, String fileName, int minLengh) throws IOException
	{
		java.io.FileReader fr = new FileReader(fileName);
		BufferedReader br = new BufferedReader(fr);
		int i = 0;
		for (String line; (line = br.readLine()) != null;){
			if (line.length() < minLengh) continue;
			arl.add(line);
			i++;
			//int id = Collections.binarySearch(arl, line);
			//if (id<0){
				//arl.add(~id, line);
			//}
		}
		br.close();
		fr.close();
		return i;
	}
	public static ArrayList<String> searchPages1() throws FacebookException{
		ArrayList<String> arl = new ArrayList<String>();
		int batchSize = 3; //Request length limit
		//String fileName1 = "D:/GROOT/DataCollector/WebContent/WEB-INF/misc/vi_VN.dic";
		String fileName2 = "D:/GROOT/DataCollector/WebContent/WEB-INF/misc/vi_VN_reduced.dic";
		try {
			//importWordsFromFile(arl, fileName1, 1);
			importWordsFromFile(arl, fileName2, 3);
			Collections.sort(arl);
			Map<String, String> paramMap = new HashMap<String, String>();
			for (int i = 0; i < arl.size(); i+= batchSize) {
				for (int k=0; k<2; k++){
					paramMap.clear();
					for (int j = i; j < i + batchSize && j < arl.size(); j++) {
						String word = arl.get(j);
						//paramMap.put("q" + (j-i), String.format(GET_PAGES_NO_COUNTRY, word, word, PAGE_SIZE, PAGE_SIZE * k));
						paramMap.put("q" + (j-i), String.format(GET_PAGES_IN_COUNTRY, word, "Vietnam", PAGE_SIZE, PAGE_SIZE * k));
					}
					Map<String, JSONArray> map =  facebook.executeMultiFQL(paramMap);
					System.out.println(map.size());
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return arl;
	}
	public static PageInfo getPageInfo(String pageId) throws FacebookException
	{
		Reading r = new Reading();
		r.fields("name,category,location");
		Page result = facebook.getPage(pageId, r);
		if (result !=null)
		{
			PageInfo pi  = new PageInfo();
			pi.setPageId(pageId);
			pi.setCategory(result.getCategory());
			pi.setPageName(result.getName());
			if (result.getLocation()!=null){
				if (result.getLocation().getCity()!=null) pi.setCity(result.getLocation().getCity());
				if (result.getLocation().getCountry()!=null) pi.setCountry(result.getLocation().getCountry());
				if (result.getLocation().getLatitude()!=null) pi.setLatitude(result.getLocation().getLatitude());
				if (result.getLocation().getLongitude()!=null) pi.setLongitude(result.getLocation().getLongitude());
			}
			return pi;
		}
		return null;
	}
	public static PageTrendInfo getPageTrendInfo(String pageId) throws FacebookException
	{
		Reading r = new Reading();
		r.fields("checkins,likes,talking_about_count");
		Page result = facebook.getPage(pageId, r);
		if (result !=null)
		{
			PageTrendInfo pti  = new PageTrendInfo();
			pti.setCheckins(result.getCheckins());
			pti.setLikes(result.getLikes());
			pti.setTalking_about_count(result.getTalkingAboutCount());
			pti.setPageId(pageId);
			return pti;
		}
		return null;
	}
	public static ArrayList<String> getPageRecentPost(String pageId, Date fromDate) throws FacebookException{
		ArrayList<String> al = new ArrayList<>();
		Reading r = new Reading();
		r.since(formatter.format(fromDate));
		r.fields("id");
		ResponseList<Post> results = facebook.getPosts(pageId, r);
		for (Post post : results) {
			al.add(post.getId());
		}
		return al;
	}
	public static PostInfo getPostInfo(String postId) throws FacebookException{
		Reading r = new Reading();
		r.fields("caption,created_time,updated_time");
		Post post = facebook.getPost(postId, r);
		if (post!=null){
			PostInfo pi = new PostInfo();
			pi.setCreateDate(post.getCreatedTime());
			pi.setUpdateDate(post.getUpdatedTime());
			pi.setPostId(postId);
			pi.setCaption(post.getCaption());
			return pi;
		}
		return null;
	}
	public static PostTrendInfo getPostTrendInfo(String postId) throws FacebookException, JSONException{
		JSONArray ja = facebook.executeFQL(String.format(GET_POST_TREND_SUMMARY,postId));
		if (ja.length()==1)
		{
			JSONObject jo = ja.getJSONObject(0);
			JSONObject ci = (JSONObject) jo.get("comment_info");
			JSONObject li = (JSONObject) jo.get("like_info");
			PostTrendInfo psi = new PostTrendInfo();
			psi.setPostId(postId);
			psi.setCommentCount(ci.getInt("comment_count"));
			psi.setLikeCount(li.getInt("like_count"));
			psi.setShareCount(jo.getInt("share_count"));
			return psi;
		}
		else
		{
			return null;					
		}
	}
}
